package com.rbac.api.service.impl;

import com.rbac.api.constant.AdminConstant;
import com.rbac.api.controller.enums.HintMessageEunm;
import com.rbac.api.controller.enums.SaveStatusTypeEnum;
import com.rbac.api.controller.request.*;
import com.rbac.api.controller.response.Response;
import com.rbac.api.exception.AdminAllException;
import com.rbac.api.mybatis.entity.AdminRolesEntity;
import com.rbac.api.mybatis.entityCus.CusAdRoleLinkedEntity;
import com.rbac.api.mybatis.entityCus.CusAdRolesListEntity;
import com.rbac.api.mybatis.entityCus.CusRoleHaveMenusMemberEntity;
import com.rbac.api.mybatis.entityCus.CusRoleHaveUsersMemberEntity;
import com.rbac.api.mybatis.mapper.*;
import com.rbac.api.service.RolesCommonService;
import com.rbac.api.service.common.AdminCommonService;
import com.rbac.api.service.common.InsActionLogService;
import com.rbac.api.service.common.SaveStatusCommService;
import com.rbac.api.utils.ApiPublicUtil;
import com.rbac.utils.commUtils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


@Service
public class RolesCommonServiceImpl implements RolesCommonService {

    ///操作管理员token公共service
    @Autowired
    private AdminCommonService adminCommonService;

    ///角色表mapper
    @Autowired
    private AdminRolesMapper adminRolesMapper;

    ///菜单表
    @Autowired
    private AdminMenusMapper adminMenusMapper;

    ///管理员表
    @Autowired
    private AdminUsersMapper adminUsersMapper;

    ///角色关联管理员mapper
    @Autowired
    private AdminRolesUsersMapper adminRolesUsersMapper;

    ///角色关联菜单mapper
    @Autowired
    private AdminRolesMenusMapper adminRolesMenusMapper;

    //事务
    @Autowired
    private TransactionService transactionService;

    ///记录操作日志service
    @Autowired
    private InsActionLogService insActionLogService;

    //日志操作
    private static final LogUtil logger = LogUtil.getLogger(RolesCommonServiceImpl.class);


    ///修改状态公共service
    @Autowired
    private SaveStatusCommService saveStatusCommService;





    ///获取角色列表
    @Override
    public Object getRolesListService(PostRolesListRequest rolesListRequest) throws Exception {
        //数据总条数
        Integer countDataNum = adminRolesMapper.getRolesListCountSelective(rolesListRequest);
        //没有数据则返回空数据
        if(countDataNum.equals(AdminConstant.DEFAULT_NO_DATA_VALUE_NUMBER)){
            return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT,new String[]{});
        }

        //当前页
        Integer pageIndex = rolesListRequest.getPageIndex();
        //页面显示条数
        Integer pageSize = rolesListRequest.getPageSize();

        PagenationUtil pageClass = new PagenationUtil(pageSize,pageIndex,countDataNum);

        //获取页面数据
        List<CusAdRolesListEntity> nowPageBasicsData = adminRolesMapper.getRolesListDataSelective(rolesListRequest,pageClass.getStartRow(),pageSize);

        ///
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT, ApiPublicUtil.AssemblyReturnItem(countDataNum,pageIndex,pageSize,nowPageBasicsData));
    }


    ///获取可操作的菜单list
    @Override
    public Object actionMenusListService() throws Exception {
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT,adminMenusMapper.actionMenusListMapper());
    }

    ///获取可操作的管理员list
    @Override
    public Object actionUsersListService() throws Exception {
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT,adminUsersMapper.actionUsersListSelective());
    }



    ///新增角色
    @Override
    public Object roleAddService(PostRoleAddRequest roleAddRequest, HttpServletRequest request) throws Exception {
        String actionNameStr = "新增角色";
        String roleNo = RandomStringUtil.getUUID();///角色编号
        String strTime = ToolUtil.getStringTodayTime();///当前时间
        String actionUid = adminCommonService.getUserNoByRequestHeader(request);
        String actionAccount = adminCommonService.getUserInfoFieldByRequestHeader(request,"account");
        String roleDiyNo = roleAddRequest.getRoleDiyNo();///角色自定义编号
        String roleName = roleAddRequest.getRoleName();///角色名称
        String roleContent = roleAddRequest.getRoleContent();///角色描述
        String usersMember = roleAddRequest.getUsersMember();///角色关联的管理员成员
        String menusMember = roleAddRequest.getMenusMember();///角色关联的菜单成员


        ///角色信息实体
        AdminRolesEntity roleOne = new AdminRolesEntity();
        roleOne.setRoleNo(roleNo);///角色编号
        roleOne.setRoleDiyNo(roleDiyNo);///角色自定义编码
        roleOne.setRoleName(roleName);///角色名称
        roleOne.setRoleContent(roleContent);///角色描述
        roleOne.setCreateUid(actionUid);///创建人编号
        roleOne.setCreateTime(ToolUtil.getDateTimeByStringTime(strTime));///创建时间


        //开启事务
        TransactionStatus transactionStatus = transactionService.begin();

        try{
            ///角色入库
            adminRolesMapper.roleAddMapper(roleOne);
            ///操作记录
            insActionLogService.InsOneActionLogService(actionNameStr,actionUid, ToolUtil.getClientIp(request),"管理员 {0} 在 {1} 进行了{2}操作，产生的数据id为{3}",actionAccount, strTime,actionNameStr,roleOne.getId());
            ///如果选择了关联的管理员
            if(StringUtils.isNotEmpty(usersMember)){
                List<CusAdRoleLinkedEntity> roleLinkedUsers = this.AssemblyLinkedData(roleNo,usersMember);
                adminRolesUsersMapper.insertManyRolesUsersDataSelective(roleLinkedUsers);
            }
            ///如果选择了关联的菜单
            if(StringUtils.isNotEmpty(menusMember)){
                List<CusAdRoleLinkedEntity> roleLinkedMenus = this.AssemblyLinkedData(roleNo,usersMember);
                adminRolesMenusMapper.insertManyRolesMenusDataSelective(roleLinkedMenus);
            }
        }catch (Exception e){
            //LOG
            logger.error(actionNameStr+"："+e);
            //回滚事务
            transactionService.rollback(transactionStatus);
            //提示出现异常
            return new Response(HintMessageEunm.EXCEPTION_ACTION_ABNORMAL_ERROR);
        }

        //提交事务
        transactionService.commit(transactionStatus);
        //操作成功
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT);
    }




    ///编辑角色（获取角色信息）
    @Override
    public Object getRoleInfoService(PostRoleGetInfoRequest roleGetInfoRequest) throws Exception {
        ///角色编号
        String roleNo = roleGetInfoRequest.getRoleNo();

        //获取角色数据
        AdminRolesEntity roleInfo;
        roleInfo = adminRolesMapper.selectInfoByRoleNoMapper(roleNo);
        if(roleInfo == null){
            return new Response(HintMessageEunm.EXCEPTION_DATA_NOT_EXISTS_ERROR_DEFAULT);
        }

        ///获取管理员成员
        List<CusRoleHaveUsersMemberEntity> usersMember = adminRolesUsersMapper.selectHaveUsersMemberByRoleNoMapper(roleNo);

        ///获取菜单成员
        List<CusRoleHaveMenusMemberEntity> menusMember = adminRolesMenusMapper.selectHaveMenusMemberByRoleNoMapper(roleNo);

        Map<String,Object> res = new HashMap<>();
        res.put("roleInfo",roleInfo);
        res.put("usersMember",usersMember);
        res.put("menusMember",menusMember);

        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT,res);
    }


    ///编辑角色（保存角色信息）
    @Override
    public Object saveRoleInfoService(PostRoleSaveRequest roleSaveRequest, HttpServletRequest request) throws Exception {
        String actionNameStr = "编辑角色";
        String strTime = ToolUtil.getStringTodayTime();///当前时间
        String actionUid = adminCommonService.getUserNoByRequestHeader(request);
        String actionAccount = adminCommonService.getUserInfoFieldByRequestHeader(request,"account");

        String roleNo = roleSaveRequest.getRoleNo();///角色编号
        String roleDiyNo = roleSaveRequest.getRoleDiyNo();///角色自定义编号
        String roleName = roleSaveRequest.getRoleName();///角色名称
        String roleContent = roleSaveRequest.getRoleContent();///角色描述
        String usersMember = roleSaveRequest.getUsersMember();///角色关联的管理员成员
        String menusMember = roleSaveRequest.getMenusMember();///角色关联的菜单成员


        ///角色信息实体
        AdminRolesEntity roleOne = new AdminRolesEntity();
        roleOne.setRoleNo(roleNo);///角色编号
        roleOne.setRoleDiyNo(roleDiyNo);///角色自定义编码
        roleOne.setRoleName(roleName);///角色名称
        roleOne.setRoleContent(roleContent);///角色描述
        roleOne.setLastUpdateUid(actionUid);///修改人编号
        roleOne.setLastUpdateTime(ToolUtil.getDateTimeByStringTime(strTime));///更新时间


        //开启事务
        TransactionStatus transactionStatus = transactionService.begin();

        try{
            ///修改角色数据
            Integer upRes = adminRolesMapper.updateDataByRoleNoMapper(roleOne);
            ///操作记录
            insActionLogService.InsOneActionLogService(actionNameStr,actionUid, ToolUtil.getClientIp(request),"管理员 {0} 在 {1} 进行了{2}操作，操作的角色编号为：{3}，操作的结果为：{4}",actionAccount, strTime,actionNameStr,roleNo,upRes);
            if(upRes == 1){
                ///清除关联的管理员数据
                adminRolesUsersMapper.deleteDataByRoleNoMapper(roleNo);
                ///如果选择了关联的管理员
                if(StringUtils.isNotEmpty(usersMember)){
                    List<CusAdRoleLinkedEntity> roleLinkedUsers = this.AssemblyLinkedData(roleNo,usersMember);
                    adminRolesUsersMapper.insertManyRolesUsersDataSelective(roleLinkedUsers);
                }
                ///清除关联的菜单数据
                adminRolesMenusMapper.deleteDataByRoleNoMapper(roleNo);
                ///如果选择了关联的菜单
                if(StringUtils.isNotEmpty(menusMember)){
                    List<CusAdRoleLinkedEntity> roleLinkedMenus = this.AssemblyLinkedData(roleNo,usersMember);
                    adminRolesMenusMapper.insertManyRolesMenusDataSelective(roleLinkedMenus);
                }
            }
        }catch (Exception e){
            //LOG
            logger.error(actionNameStr+"："+e);
            //回滚事务
            transactionService.rollback(transactionStatus);
            //提示出现异常
            return new Response(HintMessageEunm.EXCEPTION_ACTION_ABNORMAL_ERROR);
        }

        //提交事务
        transactionService.commit(transactionStatus);
        //操作成功
        return new Response(HintMessageEunm.EXCEPTION_SUCCESS_DEFAULT);
    }


    ///修改角色状态
    @Override
    public Object roleSaveStatusService(PostRoleSaveStatusRequest roleSaveStatusRequest, HttpServletRequest request) throws Exception {
        String actionNameStr = "修改角色状态";
        String nowUserNo = adminCommonService.getUserInfoFieldByRequestHeader(request,"userno");
        String actionAccount = adminCommonService.getUserInfoFieldByRequestHeader(request,"account");

        Integer id = roleSaveStatusRequest.getId();
        Integer roleStatus = roleSaveStatusRequest.getRoleStatus();
        Integer nowStatus = roleSaveStatusRequest.getNowStatus();
        Date t = ToolUtil.getNowDateTime();


        return this.saveStatusCommService.common(SaveStatusTypeEnum.ROLE_TABLE_SAVE_STATUS.getValue(),actionNameStr,actionAccount,roleStatus,nowUserNo,t,id,nowStatus,request);
    }



    ///组装角色关联数据
    private List<CusAdRoleLinkedEntity> AssemblyLinkedData(String roleNo,String linkedMember) throws Exception{
        ///去除空格、两边多余的逗号
        linkedMember = StringPubUtil.trim(StringPubUtil.trim(linkedMember," "),",");
        //提示参数错误
        if(StringUtils.isEmpty(roleNo) || StringUtils.isEmpty(linkedMember)){
            throw new AdminAllException(HintMessageEunm.EXCEPTION_PARAMETER_DEFAULT_ERROR);
        }
        String[] splitMembers = linkedMember.split(",");

        //去重
        Object[] linkedMembersArr =  ToolUtil.arrayUnique(splitMembers);

        List<CusAdRoleLinkedEntity> res = new ArrayList<CusAdRoleLinkedEntity>();
        if(linkedMembersArr.length > 0){
            for (Object linkedObj : linkedMembersArr) {
                String linkedStr = linkedObj.toString();
                if(StringUtils.isEmpty(linkedStr)){continue;}

                CusAdRoleLinkedEntity roleLinkedOne = new CusAdRoleLinkedEntity();
                roleLinkedOne.setRoleNo(roleNo);
                roleLinkedOne.setLinkedNo(linkedStr);

                res.add(roleLinkedOne);
            }
        }

        return res;
    }



}
